package com.itheima.search.service.impl;

import com.itheima.common.constants.BusinessConstants;
import com.itheima.common.constants.SystemConstants;
import com.itheima.search.document.ArticleInfoDocument;
import com.itheima.search.dto.SearchDto;
import com.itheima.search.service.ArticleInfoDocumentSearchService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @version 1.0
 * @description 说明
 * @package com.itheima.search.service.impl
 */
@Service
public class ArticleInfoDocumentSearchServiceImpl implements ArticleInfoDocumentSearchService {

    /*@Resource
    private RestHighLevelClient client;*/

    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 文章搜索功能
     *
     * @param dto
     * @return
     */
    @Override
    public List<ArticleInfoDocument> search(SearchDto dto) {
        List<ArticleInfoDocument> list = new ArrayList<>();
        // 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 使用boolQuery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 构建各种条件
        //   关键字，使用title
        boolQuery.must(QueryBuilders.matchQuery("title", dto.getSearchWords()));
        // filter
        boolQuery.filter(QueryBuilders.termQuery("isDown", 0));
        boolQuery.filter(QueryBuilders.termQuery("isDelete", 0));
        if(!dto.getTag().equals(BusinessConstants.ArticleConstants.DEFAULT_TAG)){
            // 按频道过滤
            boolQuery.filter(QueryBuilders.termQuery("channelId", Integer.parseInt(dto.getTag())));
        }
        // 小于传过来的最小时间，解决深度分页问题
        boolQuery.filter(QueryBuilders.rangeQuery("publishTime").lt(dto.getMinBehotTime().getTime()));
        // 排序 publishTime 降序
        queryBuilder.withSort(SortBuilders.fieldSort("publishTime").order(SortOrder.DESC));
        // 分页 获取size, from 0
        queryBuilder.withPageable(PageRequest.of(0, 10));
        // 高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder().field("title")
            .preTags("<em>").postTags("</em>").requireFieldMatch(false);
        queryBuilder.withHighlightBuilder(highlightBuilder);

        queryBuilder.withQuery(boolQuery);

        NativeSearchQuery searchQuery = queryBuilder.build();
        // 查询、得到结果
        SearchHits<ArticleInfoDocument> searchResult = elasticsearchRestTemplate.search(searchQuery, ArticleInfoDocument.class);
        // 解析结果
        List<SearchHit<ArticleInfoDocument>> searchHits = searchResult.getSearchHits();
        if(!CollectionUtils.isEmpty(searchHits)){
            // 遍历
            for (SearchHit<ArticleInfoDocument> hit : searchHits) {
                // 每个命中的结果
                ArticleInfoDocument articleInfoDocument = hit.getContent();
                list.add(articleInfoDocument);
                // 解析高亮
                List<String> title = hit.getHighlightField("title");
                if(!CollectionUtils.isEmpty(title)){
                    String highlight = String.join(",", title);
                    // 使用高亮替换原来的标题
                    articleInfoDocument.setTitle(highlight);
                }
            }
        }
        // 返回数据
        return list;
    }
}
